package com.xdf.xzymanagementsystem.config;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import javax.servlet.DispatcherType;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.cc.alltype.UUID;

@Slf4j
public class LogInterceptor implements AsyncHandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (request.getDispatcherType() != DispatcherType.REQUEST) {
            // 非 DispatcherType.REQUEST 分发类型，尝试从 Attribute 获取 LOG_TRACE_ID
            MDC.put("traceId", (String) request.getAttribute("traceId"));
            log.info("preHandle Non DispatcherType.REQUEST type with DispatcherType {}", request.getDispatcherType());
            return true;
        }
        // 如果本次调用来自上游服务，那么尝试从请求头获取上游传递的 traceId
        String traceId = request.getHeader("traceId");
        if (traceId == null) {
            // 本服务节点是起始服务节点，设置 traceId
//            traceId = UUID.randomUUID().toString();
            traceId = UUID.getNoSeparator();
        }
        MDC.put("traceId", traceId);
        // 异步处理会在内部进行 Request 转发，通过 Attribute 携带 traceId
        request.setAttribute("traceId", traceId);
        log.info("preHandle DispatcherType.REQUEST type with DispatcherType {}", request.getDispatcherType());
        return true;
    }

    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 清理 MDC
        log.info("afterConcurrentHandlingStarted Clearing MDC.");
        MDC.clear();
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) {
        // 清理 MDC
        log.info("afterCompletion Clearing MDC with DispatcherType {}", request.getDispatcherType());
        MDC.clear();
    }
}
